package com.topsec.erp.util;

import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by lx1 on 2017/5/25.
 */
public class ConvertUtil<T> {
    public Specification<T> getWhereClause(final Map<String, String> params) {
        final Map<String, String> paramsa = params;
        return new Specification<T>() {
            /**
             *
             * @param root 定义查询的From子句中能出现的类型
             * @param criteriaQuery 安全查询主语句
             * @param criteriaBuilder 安全查询创建工厂
             * @return
             */
            @Override
            public Predicate toPredicate(Root<T> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

                // or 条件
                List<Predicate> predicates = new ArrayList<Predicate>();

                // 创建具体查询条件
                Predicate predicate = criteriaBuilder.conjunction();
                for (Map.Entry<String, String> p : paramsa.entrySet()) {
                    if (StringUtils.isNotBlank(p.getValue()) && (p.getKey().equals("t_responsible") || p.getKey().equals("task_founder") || p.getKey().equals("dutyPersron") || p.getKey().equals("receivePersion"))) {

                        System.out.println(" ===>>> 分页条件查询进入 or");
                        predicates.add(criteriaBuilder.equal(root.<String>get(p.getKey()), StringUtils.trim(p.getValue())));

                    } else if (StringUtils.isNotBlank(p.getValue()) && (p.getKey().equals("ipProto"))) {

                        System.out.println(" ===>>> ipProto分页条件查询进入  or");
                        String ipProto = p.getValue();
                        List<String> unjson = JsonUtil.unjson(ipProto, new TypeToken<List<String>>() {
                        }.getType());
                        for (String s : unjson) {
                            predicates.add(criteriaBuilder.like(root.<String>get(p.getKey()), "%" + s + "%"));
                        }
                        
                    } else if (StringUtils.isNotBlank(p.getValue()) && !p.getKey().contains("Time") && !p.getKey().contains("starIpLong") && !p.getKey().contains("endIpLong")) {
                        System.out.println(" ===>>> 分页条件查询进入 and");
                        if (WhereEqual.equalSql.containsKey(p.getKey())) {
                            // 精确搜索
                            predicate.getExpressions().add(criteriaBuilder.equal(root.<String>get(p.getKey()), StringUtils.trim(p.getValue())));
                        } else {
                            // 模糊搜索
//                            predicate.getExpressions().add(criteriaBuilder.like(root.<String>get(p.getKey()), "%" + StringUtils.trim(p.getValue()) + "%"));
                        }
                    }
                }

                if (predicates.size() > 0) {
                    predicate.getExpressions().add(criteriaBuilder.or(predicates.toArray(new Predicate[predicates.size()])));
                }


                //此处时间格式一定要和页面时间设置的格式一样，如不同，时间转换会出问题
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date startTime = null;  //页面传过来的参数值



                if (StringUtils.isNotBlank(paramsa.get("startTime"))) {
                    // 前端页面时间选择项选择第一个开始时间、第二个开始时间和第一个结束时间、第二个结束时间
                    try {
                        startTime = sdf.parse((String) paramsa.get("startTime"));
                        predicate.getExpressions().add(criteriaBuilder.greaterThanOrEqualTo(root.<Date>get("startTime"), startTime));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (StringUtils.isNotBlank(paramsa.get("startTime1"))) {
                    // 前端页面时间选择项选择第一个开始时间、第二个开始时间和第一个结束时间、第二个结束时间
                    try {
                        startTime = sdf.parse((String) paramsa.get("startTime1"));
                        predicate.getExpressions().add(criteriaBuilder.lessThanOrEqualTo(root.<Date>get("startTime"), startTime));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (StringUtils.isNotBlank(paramsa.get("endTime"))) {
                    // 前端页面时间选择项选择第一个开始时间、第二个开始时间和第一个结束时间、第二个结束时间
                    try {
                        startTime = sdf.parse((String) paramsa.get("endTime"));
                        predicate.getExpressions().add(criteriaBuilder.greaterThanOrEqualTo(root.<Date>get("endTime"), startTime));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (StringUtils.isNotBlank(paramsa.get("endTime1"))) {
                    // 前端页面时间选择项选择第一个开始时间、第二个开始时间和第一个结束时间、第二个结束时间
                    try {
                        startTime = sdf.parse((String) paramsa.get("endTime1"));
                        predicate.getExpressions().add(criteriaBuilder.lessThanOrEqualTo(root.<Date>get("endTime"), startTime));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return predicate;
            }
        };
    }
}
